﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;

namespace Roaming
{
 /// <summary>
    /// Class RoamingObservableCollection
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class RoamingObservableCollection<T> : ObservableKeyedCollection<string, T> where T : RoamingObservableDictionary, new()
    {
        /// <summary>
        /// Inserts the item.
        /// </summary>
        /// <param name="index">The index.</param>
        /// <param name="item">The item.</param>
        protected override void InsertItem(int index, T item)
        {
            if (base.Contains(item.Key))
            {
                var key = base.GetKeyForItem(item);
                var old = base[key];
                old.LoadFrom(item);

                //base.SetItem(pos, item);
            }
            else
            {
                base.InsertItem(index, item);
            }

        }

        /// <summary>
        /// Raises the <see cref="E:CollectionChanged" /> event.
        /// </summary>
        /// <param name="e">The <see cref="NotifyCollectionChangedEventArgs"/> instance containing the event data.</param>
        protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            Debug.WriteLine("OnCollectionChanged " + e.Action);
            if (_container != null)
            {
                if (e.NewItems != null)
                {
                    foreach (RoamingObservableDictionary item in e.NewItems)
                    {
                        Debug.WriteLine("Roaming item " + item.Key);
                        var tmpItem = new T();
                        tmpItem.Container = _container.CreateContainer(item.Key, ApplicationDataCreateDisposition.Always);
                        tmpItem.LoadFrom(item);
                    }
                }
                if (e.OldItems != null)
                {
                    foreach (RoamingObservableDictionary item in e.OldItems)
                    {
                        Debug.WriteLine("Delete item " + item.Key);
                        // do cleanup here;
                    }
                }

            }
            if (!_deferCollectionChanged)
            {
                base.OnCollectionChanged(e);
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="RoamingObservableCollection{T}"/> class.
        /// </summary>
        public RoamingObservableCollection()
            : base(x => x.Key)
        {

        }

        /// <summary>
        /// The _container
        /// </summary>
        private ApplicationDataContainer _container;
        /// <summary>
        /// Gets or sets the container.
        /// </summary>
        /// <value>The container.</value>
        public ApplicationDataContainer Container
        {
            get
            {
                return _container;
            }
            set
            {
                _container = value;
                if (_container != null)
                {
                    LoadFrom(_container.Containers);
                }
            }
        }
        /// <summary>
        /// The _defer collection changed
        /// </summary>
        private bool _deferCollectionChanged;
        /// <summary>
        /// Loads from.
        /// </summary>
        /// <param name="containers">The containers.</param>
        public void LoadFrom(IEnumerable<KeyValuePair<string, ApplicationDataContainer>> containers)
        {
            _deferCollectionChanged = true;
            foreach (var item in containers)
            {
                var obj = new T();
                obj.Container = _container.Containers[item.Key];
                this.Add(obj);
            }
            _deferCollectionChanged = false;
            this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }
    }
}
